﻿//-----------------------------------------------------------------------
// <copyright file="MainPage.xaml.cs" company="FIT VUT">
//     Copyright (c) FIT VUT. All rights are reserved.
// </copyright>
//-----------------------------------------------------------------------

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using BookCaching.CustomControls;
using BookCaching.Data;
using BookCaching.Misc;
using BookCaching.Settings;
using Microsoft.Phone.Controls;
using BookCaching.Data.Storage;
using System.Device.Location;

namespace BookCaching
{
    public partial class MainPage : PhoneApplicationPage
    {
        private int booksListsLoaded;
        private LoggedInUserData loggedInUserData;
        UnregisteredUserData unregisteredUserData;
        // Constructor
        public MainPage()
        {
            this.InitializeComponent();

            booksListsLoaded = 0;

            currentPositionPushpin.Template = (ControlTemplate)(App.Current.Resources["PushpinCurrentPosition"]);
        }

        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);

            if (this.NavigationContext.QueryString.ContainsKey("CollectibleName"))
            {
                string collectibleName = NavigationContext.QueryString["CollectibleName"];
            }

            //IsolatedStorageHandler.Instance.AddOrUpdateValue("Logged_user", new User(5, "Fake User", "blah"));

            User loggedUser = IsolatedStorageHandler.Instance.GetValueOrDefault<User>("Logged_user", null);
            //User loggedUser = CurrentSettings.Instance.User;
            if (loggedUser == null)
            { // user not logged, show login control
                UnregisteredUserData unregUserData = new UnregisteredUserData();
                unregUserData.UserLoggedIn += UserLoggedIn;
                this.userDataGrid.Children.Add(unregUserData);
            }
            else
            {// user logged, save to current settings, load books, show loggedInUserData

                Knihotoc_WCFService.Knihotoc_WP7ServiceClient client = new Knihotoc_WCFService.Knihotoc_WP7ServiceClient();
                client.LoginUserCompleted += Knihotoc_WP7ServiceClient_LoginUserCompleted;
                client.LoginUserAsync(loggedUser.UserName, loggedUser.Password);                
            }
            
            //List<Place> commonPlaces = new List<Place>()
            //{
            //    new Place(0, "Hawthorne Grill", 10.5f, 10.0f, "/Images/BookCovers/KantosHyperionu.jpg"),
            //    new Place(1, "Bad Mother Fucker Wallet", 10.0f, 10.0f, "/Images/BookCovers/KantosHyperionu.jpg"),
            //    new Place(2, "Honey Bunny", 10.0f, 10.0f, "/Images/BookCovers/KantosHyperionu.jpg")
            //};

            //IEnumerable commonPlacesByName;


            //commonPlacesByName = from commonPlace in commonPlaces
            //                     group commonPlace by commonPlace.Name into c
            //                     orderby c.Key ascending
            //                     select new Group<Place>(c.Key, c);

            //this.commonPlacesListBox.ItemsSource = commonPlaces;

            //string test1 = this.commonPlacesListBox.Items[0].ToString();

            //int test = this.commonPlacesListBox.Items.Count;

            //LoggedInUserData userData = new LoggedInUserData();
            //userData.ShowAllMyBooks += new EventHandler(this.UserData_ShowAllMyBooks);
            //this.userDataGrid.Children.Add(userData);

            //LoggedInUserData userData = new LoggedInUserData();
            //userData.ShowAllMyBooks += new EventHandler(this.UserData_ShowAllMyBooks);
            //this.userDataGrid.Children.Add(userData);

            CurrentSettings.Instance.CurrentPositionChanged += CurrentSettings_CurrentPositionChanged;
            this.currentPositionPushpin.Location = CurrentSettings.Instance.CurrentPosition;
            
            this.map.Center = this.currentPositionPushpin.Location;
            this.map.ZoomLevel = DefaultSettings.Instance.MapZoomLevel;
            
            //CurrentSettings.Instance.Knihotoc_WP7ServiceClient.GetPlacesByDistanceAsync(CurrentSettings.Instance.CurrentPosition.Latitude,
            //    CurrentSettings.Instance.CurrentPosition.Longitude,
            //    CurrentSettings.Instance.Distance, null);

            LoadNearPlaces();
        }

        void Knihotoc_WP7ServiceClient_GetPlacesByDistanceCompleted(object sender, Knihotoc_WCFService.GetPlacesByAreaCompletedEventArgs e)
        {
            List<Knihotoc_WCFService.Place> lp = e.Result.ToList();
            List<Place> placesSource = new List<Place>();
            Place place;

            foreach (Knihotoc_WCFService.Place p in lp)
            {
                place = new Place();

                place.Address = new Address(p.Address);
                place.Description = p.Description;
                place.ID = p.ID;
                //place.LogoImagePath = 
                place.Name = p.Name;

                placesSource.Add(place);
            }

            // sort and order ascending
            switch (CurrentSettings.Instance.PlaceListSortingBy)
            {
                case SortingPlacesBy.distance:
                case SortingPlacesBy.name:
                    placesSource.Sort((x, y) => string.Compare(x.Name, y.Name));
                    break;
                default:
                    throw new ArgumentOutOfRangeException("This value of the enum is not valid!");
            }

            // order descending - just reverse list
            switch (CurrentSettings.Instance.PlaceListOrderingOrder)
            {
                case OrderingOrder.ascending:
                    break;
                case OrderingOrder.descending:
                    placesSource.Reverse();
                    break;
                default:
                    throw new ArgumentOutOfRangeException("This value of the enum is not valid!");
            }

            commonPlacesListBox.ItemsSource = placesSource;

            ((Knihotoc_WCFService.Knihotoc_WP7ServiceClient)sender).CloseAsync();
        }

        //void Knihotoc_WP7ServiceClient_GetUserByIdCompleted(object sender, Knihotoc_WCFService.GetUserByIdCompletedEventArgs e)
        //{
        //    BookCaching.Knihotoc_WCFService.User userDatabase = e.Result;
        //    CurrentSettings.Instance.User = new User(userDatabase);
        //    userLoaded();

        //    CurrentSettings.Instance.Knihotoc_WP7ServiceClient.GetUserByIdCompleted -= Knihotoc_WP7ServiceClient_GetUserByIdCompleted;

        //    CurrentSettings.Instance.Knihotoc_WP7ServiceClient.GetBooksOwnedByUserCompleted += new EventHandler<Knihotoc_WCFService.GetBooksOwnedByUserCompletedEventArgs>(client_GetBooksOwnedByUserCompleted);
        //    CurrentSettings.Instance.Knihotoc_WP7ServiceClient.GetBooksOwnedByUserAsync(CurrentSettings.Instance.User.ID);

        //    CurrentSettings.Instance.Knihotoc_WP7ServiceClient.GetBooksBorrowedByUserCompleted += new EventHandler<Knihotoc_WCFService.GetBooksBorrowedByUserCompletedEventArgs>(client_GetBooksBorrowedByUserCompleted);
        //    CurrentSettings.Instance.Knihotoc_WP7ServiceClient.GetBooksBorrowedByUserAsync(CurrentSettings.Instance.User.ID);

        //    CurrentSettings.Instance.Knihotoc_WP7ServiceClient.GetFoundBooksCompleted += new EventHandler<Knihotoc_WCFService.GetFoundBooksCompletedEventArgs>(client_GetFoundBooksCompleted);
        //    CurrentSettings.Instance.Knihotoc_WP7ServiceClient.GetFoundBooksAsync(CurrentSettings.Instance.User.ID);
        //}

        protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
        {
            CurrentSettings.Instance.CurrentPositionChanged -= CurrentSettings_CurrentPositionChanged;
        }

        protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
        {
            throw new Exception("Exit application");
        }

        void userLoaded()
        {
            // update content of fields
            User loggedUser = CurrentSettings.Instance.User;
            loggedInUserData = new LoggedInUserData(loggedUser);
            loggedInUserData.ShowAllMyBooks += new EventHandler(this.UserData_ShowAllMyBooks);
            this.userDataGrid.Children.Clear();
            this.userDataGrid.Children.Add(loggedInUserData);
            // save new data to iso_storage
            IsolatedStorageHandler.Instance.AddOrUpdateValue("Logged_user", CurrentSettings.Instance.User);
        }

        void booksLoaded()
        {
            // save new data to iso_storage
            IsolatedStorageHandler.Instance.AddOrUpdateValue("Logged_user", CurrentSettings.Instance.User);
            loggedInUserData.reloadValues();
            //if (booksListsLoaded == 0)
            //{
                

            //    booksListsLoaded++;
            //    return;
            //}
            //else
            //{
            //    booksListsLoaded = 0;
            //}
            
        }

        void Knihotoc_WP7ServiceClient_LoginUserCompleted(object sender, Knihotoc_WCFService.LoginUserCompletedEventArgs e)
        {
            if (e.Error != null || e.Result == null)
            {
                return;
            }

            CurrentSettings.Instance.User = new Data.User(e.Result);
            loggedInUserData = new LoggedInUserData(new User(e.Result));
            loggedInUserData.ShowAllMyBooks += new EventHandler(this.UserData_ShowAllMyBooks);
            this.userDataGrid.Children.Add(loggedInUserData);
        }

        void CurrentSettings_CurrentPositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e)
        {
            this.currentPositionPushpin.Location = e.Position.Location;
            this.map.Center = this.currentPositionPushpin.Location;
            this.map.ZoomLevel = DefaultSettings.Instance.MapZoomLevel;
            UpdatePrecision(e.Position.Location);

            LoadNearPlaces();
        }

        private void LoadNearPlaces()
        {
            Knihotoc_WCFService.Knihotoc_WP7ServiceClient client = new Knihotoc_WCFService.Knihotoc_WP7ServiceClient();
            client.GetPlacesByAreaCompleted += Knihotoc_WP7ServiceClient_GetPlacesByDistanceCompleted;
            if (CurrentSettings.Instance.CurrentPosition != null)
            {
                client.GetPlacesByAreaAsync(CurrentSettings.Instance.CurrentPosition.Latitude - 2,
                                            CurrentSettings.Instance.CurrentPosition.Longitude - 2,
                                            CurrentSettings.Instance.CurrentPosition.Latitude + 2,
                                            CurrentSettings.Instance.CurrentPosition.Longitude + 2,
                                            null);
            }
        }

        private void UpdatePrecision(GeoCoordinate location)
        {
            precision.Visibility = Visibility.Collapsed;
            if (location == null)
                return;

            precision.Visibility = Visibility.Visible;
            precision.Locations = new Microsoft.Phone.Controls.Maps.LocationCollection();

            var earthRadius = 6371;
            var lat = location.Latitude * Math.PI / 180.0; //radians 
            var lon = location.Longitude * Math.PI / 180.0; //radians 
            var d = location.HorizontalAccuracy / 1000 / earthRadius; // d = angular distance covered on earths surface 

            for (int x = 0; x <= 360; x++)
            {
                var brng = x * Math.PI / 180.0; //radians 
                var latRadians = Math.Asin(Math.Sin(lat) * Math.Cos(d) + Math.Cos(lat) * Math.Sin(d) * Math.Cos(brng));
                var lngRadians = lon + Math.Atan2(Math.Sin(brng) * Math.Sin(d) * Math.Cos(lat), Math.Cos(d) - Math.Sin(lat) * Math.Sin(latRadians));

                var pt = new GeoCoordinate(180.0 * latRadians / Math.PI, 180.0 * lngRadians / Math.PI);
                precision.Locations.Add(pt);
            }
        }

        private void UserData_ShowAllMyBooks(object sender, EventArgs e)
        {
            NavigationService.Navigate(new Uri("/Pages/BookListPage.xaml", UriKind.Relative));
        }

        private void ThemeListPicker_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            switch (((sender as ListPicker).SelectedItem as ListPickerItem).Name)
            {
                case "themePhone":
                    CurrentSettings.Instance.SetTheme(
                                                      (Color)Application.Current.Resources["PhoneAccentColor"],
                                                      (Color)Application.Current.Resources["PhoneBackgroundColor"]);
                    break;
                case "themedarkYellow":
                    CurrentSettings.Instance.SetTheme(Colors.Yellow, Colors.Black);
                    break;
                case "themeLightBlue":
                    CurrentSettings.Instance.SetTheme(Colors.Blue, Colors.White);
                    break;                    
            }
        }

        private void CommonPlaceItemTemplate_Tap(object sender, System.Windows.Input.GestureEventArgs e)
        {
            int placeID = ((GridID)sender).ID;

            NavigationService.Navigate(new Uri("/Pages/CommonPlaceDetailPage.xaml?PlaceID=" + placeID.ToString(), UriKind.Relative));
        }

        private void AllPlacesButton_Click(object sender, RoutedEventArgs e)
        {
            NavigationService.Navigate(new Uri("/Pages/CommonPlaceListPage.xaml", UriKind.Relative));
        }

        private void TestDatabase_Click_1(object sender, RoutedEventArgs e)
        {
            try
            {
                //client.GetBookNameByIDCompleted += client_GetBookByNameByIDCompleted;
                //client.GetBookNameByIDAsync(0);
                //client.GetBookByIDCompleted += client_GetBookByIDCompleted;
                //client.GetBookByIDAsync(5);
                //client.GetBooksInLocationCompleted += client_GetBooksInLocationCompleted;
                //client.GetBooksInLocationAsync(0, 0, 1, null);
                /*client.GetBooksOwnedByUserCompleted += client_GetBooksOwnedByUserCompleted;
                client.GetBooksOwnedByUserAsync(2);
                client.GetBooksBorrowedByUserCompleted += client_GetBooksBorrowedByUserCompleted;
                client.GetBooksBorrowedByUserAsync(1);*/
                
            }
            catch (System.ServiceModel.CommunicationException)
            {
            }
        }

        private void switchUserButton_Click_1(object sender, RoutedEventArgs e)
        {
            this.userDataGrid.Children.Clear();
            unregisteredUserData = new UnregisteredUserData();

            this.userDataGrid.Children.Add(unregisteredUserData);

            // navigate to the panorama item that we want (user login)
            this.panorama.SetValue(Panorama.SelectedItemProperty, this.panorama.Items[0]);
            this.panorama.Measure(new Size());
        }

        void UserLoggedIn(object sender, EventArgs e)
        {
            userLoaded();
        }

        private void NavigateToMap()
        {
            if (CurrentSettings.Instance.User != null)
            {
                NavigationService.Navigate(new Uri("/Pages/MapPage.xaml", UriKind.Relative));
            }
        }

        private void Map_Tap(object sender, System.Windows.Input.GestureEventArgs e)
        {
            NavigateToMap();
        }

        private void Map_DoubleTap(object sender, System.Windows.Input.GestureEventArgs e)
        {
            NavigateToMap();
        }

        private void Map_ManipulationStarted(object sender, ManipulationStartedEventArgs e)
        {
            NavigateToMap();
        }

        private void Map_Pan(object sender, Microsoft.Phone.Controls.Maps.MapDragEventArgs e)
        {
            NavigateToMap();
        }

        private void Map_Zoom(object sender, Microsoft.Phone.Controls.Maps.MapZoomEventArgs e)
        {
            NavigateToMap();
        }


        /*void client_GetBooksInLocationCompleted(object sender, Knihotoc_WCFService.getb.GetBooksInLocationCompletedEventArgs e)
        {
            List<Knihotoc_WCFService.Book> lb = e.Result.ToList();
        }

        void client_GetBookByIDCompleted(object sender, Knihotoc_WCFService.GetBookByIDCompletedEventArgs e)
        {
            Knihotoc_WCFService.Book testBook = e.Result;            
            //testDatabaseText.Text = testBook.Title;
        }

        void client_GetBooksOwnedByUserCompleted(object sende, Knihotoc_WCFService.GetBooksOwnedByUserCompletedEventArgs e)
        {
            int i = 0;
        }

        void client_GetBooksBorrowedByUserCompleted(object sende, Knihotoc_WCFService.GetBooksBorrowedByUserCompletedEventArgs e)
        {
            int i = 0;
        }
        */
        
    }
}
